﻿// 4227. 找路.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <queue>

using namespace std;
/*
https://www.acwing.com/problem/content/4230/


给定一个 n 行 m列的方格矩阵。

其中有些方格是空地（可以进入），有些方格是餐厅（可以进入），有些方格是障碍（不可进入）。

开始时，小 Y和小 M各自位于一个空地方格中。

每个人都可以沿上下左右四个方向进行移动，移动一格距离需要花费 11分钟时间。

他们希望选择一家餐厅进行聚餐，要求两人从各自出发点到达该餐厅所花费的时间之和尽可能小。

输出这个最小时间和。

输入格式
输入包含多组测试数据。

每组数据第一行包含两个整数 n,m。

接下来 n行，包含一个 n×m的字符矩阵。

矩阵中只包含以下五种字符：

# 表示障碍方格。
. 表示空地方格。
Y 表示小 Y
 所在的空地方格，有且仅有一个。
M 表示小 M
 所在的空地方格，有且仅有一个。
@ 表示餐厅。
输出格式
每组数据输出一行答案，表示最小时间和。

保证一定有解。

数据范围
最多包含 100 组数据。
2≤n,m≤200。

输入样例：
4 4
Y.#@
....
.#..
@..M
4 4
Y.#@
....
.#..
@#.M
5 5
Y..@.
.#...
.#...
@..M.
#...#
输出样例：
66
88
66
*/

const int N = 210;
char gra[N][N];
int ymap[N][N];
int mmap[N][N];
int Ax, Ay, Bx, By;
int n, m;
const int addx[] = { 1,-1,0,0 };
const int addy[] = { 0,0,1,-1 };


void bfs(int inx,int iny,int mm[][N]) {
	queue<pair<int,int> > q;
	q.push({ inx ,iny });
	mm[inx][iny] = 0;

	while (!q.empty()) {
		int x = q.front().first; int y = q.front().second;
		int step = mm[x][y];
		q.pop();

		for (int i = 0; i < 4; i++) {
			int newx = x + addx[i]; int newy = y + addy[i];
			if (newx >= 0 && newx < n && newy >= 0 && newy < m && gra[newx][newy] != '#' 
				&& mm[newx][newy] == 0x3f3f3f3f) 
			{
				mm[newx][newy] = step + 1;
				q.push({ newx,newy });
			}

		}
	}
	



	return;
}


void solve() {
	memset(ymap, 0x3f, sizeof ymap);
	memset(mmap, 0x3f, sizeof mmap);

	bfs(Ax,Ay,ymap); bfs(Bx,By,mmap);

	int ans = 0x3f3f3f3f;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (gra[i][j] == '@') {
				ans = min(ans, mmap[i][j] + ymap[i][j]);
			}

		}
	}

	cout << ans*11 << endl;
	return;
}


int main()
{
	while (cin >> n >> m) {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				cin >> gra[i][j];
				if (gra[i][j] == 'Y') {	Ax = i; Ay = j;}
				if (gra[i][j] == 'M') { Bx = i; By = j;}
			}
		}

		solve();
	}


	return 0;
}

 